package com.etone.smartAudit.dto;

import cn.hutool.core.util.StrUtil;
import com.etone.smartAudit.error.CustomParameterizedException;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;
import java.util.List;
import java.util.StringJoiner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @author: sovy
 * @date: 2020/9/29
 * @description:
 */
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Data
@ApiModel(value = "参数详情")
public class ParamDTO implements Serializable {

    @ApiModelProperty("字段名称")
    private String name;

    @ApiModelProperty("条件(eq(精确查找),like(模糊查找),bw(范围查找),in(列表范围查找))")
    private String operation;

    @ApiModelProperty("值,如果operation=bw，value是较小值;operation=in,value是一个数组")
    private Object value;

    @ApiModelProperty("值,如果operation=bw，value1较大值")
    private Object value1;

    /**
     * 获取操作符
     *
     * @return
     */
    public String sqlOperation() {
        return "eq".equals(operation) ? "=" : ("bw".equals(operation) ? "between" : operation);
    }

    /**
     * 是否含有sql注入，返回true表示含有
     *
     * @param obj
     * @return
     */
    public static boolean containsSqlInjection(Object obj) {
//        "'|\"|>|..|and|exec|insert|select|delete|update|count|*|%|chr|mid|master|truncate|char|declare|script|frame|;|or|-|+|,|)|etc|style|expression|="
        Pattern pattern = Pattern.compile("\\b(and|exec|insert|select|drop|grant|alter|delete|update|count|chr|mid|master|truncate|char|declare|or|etc|style|expression|etc|style)\\b|(\\*|;|\\+|'|%|>|=)");
        Matcher matcher = pattern.matcher(obj.toString().toLowerCase());
        return matcher.find();
    }

    /**
     * 组装where条件
     *
     * @return
     */
    public String assembleWhere() {

        //判断value value1 是否有sql注入
        if (value != null && StrUtil.isNotEmpty(value.toString())) {
            if (containsSqlInjection(value)) {
                throw new CustomParameterizedException("请输入合法参数");
            }
        }
        //判断value value1 是否有sql注入
        if (value1 != null && StrUtil.isNotEmpty(value1.toString())) {
            if (containsSqlInjection(value1)) {
                throw new CustomParameterizedException("请输入合法参数");
            }
        }
        //name value1 是否有sql注入
        if (name != null && StrUtil.isNotEmpty(name.toString())) {
            if (containsSqlInjection(name)) {
                throw new CustomParameterizedException("请输入合法参数");
            }
        }

        if ("like".equals(operation)) {
//            return name + " " + sqlOperation() + " concat('%','" + value + "','%')";
            return name + " " + sqlOperation() + "'%" + value + "%'";
        }
        if ("bw".equals(operation)) {
            return name + " " + sqlOperation() + " " + value + " and " + value1;
        }
        if ("in".equals(operation)) {
            if (value instanceof List) {
                List inValues = (List) value;
                if (inValues != null && inValues.size() > 0) {
                    try {
//                        return name + " " + sqlOperation() + " ('" + inValues.stream().collect(Collectors.joining("','")) + "')";
                        StringJoiner sb = new StringJoiner(",");
                        inValues.stream().forEach(val->{
                            sb.add(val+"");
                        });
//                        return name + " " + sqlOperation() + " ('" + inValues.stream().collect(Collectors.joining("','")) + "')";
                        return name + " " + sqlOperation() + " ('" + sb.toString() + "')";
                    } catch (Exception e) {
                        e.printStackTrace();
                    }

                }

            }
            throw new CustomParameterizedException("无效参数");
        }
        return name + " " + sqlOperation() + " '" + value + "'";
    }

}
